<!-- eslint-disable vue/no-v-html -->
<script setup lang="ts" name="result">
import { renderSearchResult, eventBus, getScrollParent } from '@/utils'

const expand = ref<boolean>(false)

const innerActiveIndex = ref(0)

const props = withDefaults(
  defineProps<{
    searchBarVal: string
    searchResult: SearchResult
    sectionIndex: number
    activeIndex: number
    title: string
  }>(),
  {
    searchResult: () => []
  }
)

const searchResultView = computed(() => {
  if (expand.value) {
    return props.searchResult
  }

  return props.searchResult.slice(0, 9)
})

onUnmounted(() => {
  eventBus.off('selectChange')
  eventBus.off('selectItem')
})

onMounted(() => {
  eventBus.on('selectChange', (event) => {
    const data = event as selectChangeData
    const isSectionChange = data.curSectionIndex !== undefined
    const curSelectionIndex = data.curSectionIndex ?? data.startSectionIndex

    if (props.sectionIndex !== curSelectionIndex) {
      return
    }

    console.log(
      data,
      `select change isSectionChange: ${isSectionChange}, curSelectionIndex: ${curSelectionIndex}`
    )

    if (isSectionChange) {
      if (searchResultView.value.length > 0) {
        if (data.action === 'right' || data.action === 'down') {
          const firstLineMaxIndex =
            searchResultView.value.length % 9 === searchResultView.value.length
              ? searchResultView.value.length
              : 9
          innerActiveIndex.value = Math.min(data.referenceIndx ?? 0, firstLineMaxIndex - 1)
        } else {
          if (data.referenceIndx !== undefined) {
            const lastLineFirstEleIndex = (Math.ceil(searchResultView.value.length / 9) - 1) * 9
            innerActiveIndex.value = Math.min(
              lastLineFirstEleIndex + data.referenceIndx,
              searchResultView.value.length - 1
            )
          } else {
            innerActiveIndex.value = searchResultView.value.length - 1
          }
        }
      } else if (data.startSectionIndex !== props.sectionIndex) {
        eventBus.emit('sectionChange', data)
      }
    } else {
      let val = innerActiveIndex.value
      if (data.action === 'right') {
        val += 1
      } else if (data.action === 'down') {
        val += 9
        if (val >= searchResultView.value.length) {
          const lastLineFirstEleIndex = (Math.ceil(searchResultView.value.length / 9) - 1) * 9
          if (innerActiveIndex.value < lastLineFirstEleIndex) {
            val = searchResultView.value.length - 1
          }
        }
      } else if (data.action === 'up') {
        val -= 9
      } else {
        val -= 1
      }

      if (val < 0 || val >= searchResultView.value.length) {
        if (data.action === 'up' || data.action === 'down') {
          data.referenceIndx = innerActiveIndex.value % 9
        }
        eventBus.emit('sectionChange', data)
        return
      }
      innerActiveIndex.value = val
    }

    //焦点元素可见
    nextTick(() => {
      const target = document.querySelector('.item-active')
      if (target) {
        //滚动使元素可见
        const scrollParent = getScrollParent(target)
        if (scrollParent) {
          const rect = target.getBoundingClientRect()
          const parentRect = scrollParent.getBoundingClientRect()
          if (rect.top < parentRect.top) {
            scrollParent.scrollTop -= parentRect.top - rect.top
          } else if (rect.bottom > parentRect.bottom) {
            scrollParent.scrollTop += rect.bottom - parentRect.bottom
          }
        }
      }
    })
  })

  eventBus.on('selectItem', () => {
    if (props.sectionIndex !== props.activeIndex) {
      return
    }

    emits('open', searchResultView.value[innerActiveIndex.value])
  })
})

watch(
  () => props.searchBarVal,
  () => {
    expand.value = false
    innerActiveIndex.value = 0
  }
)

// emits
const emits = defineEmits<{
  open: [SearchResultItem]
}>()

// slots
// defineSlots<{
//   default(props: { attr1?: string }): any
// }>()

const clickItem = (item) => {
  emits('open', item)
}

const contextmenu = (e) => {
  e.preventDefault()
  e.stopPropagation()

  //TODO: 右键菜单
}

const itemKey = (item: SearchResultItem) => {
  return item.type + item.name + (item.type === 'plugin' ? item.code + item.label : item.path)
}
const itemName = (item: SearchResultItem) => {
  return item.type === 'app' ? item.name : item.label
}

//model
// const visible = defineModel<boolean>('visible', { default: false })
</script>

<template>
  <div v-show="searchResultView.length > 0" class="w-full box-border flex flex-col">
    <div
      class="titlebar h-28px text-14px font-bold flex flex-row px-12px items-center justify-between"
    >
      <span>{{ title }}</span>
      <span
        v-if="searchResult.length > 9 && !expand"
        class="text-12px font-normal cursor-pointer"
        @click="expand = true"
        >展开({{ searchResult.length }})</span
      >
    </div>

    <n-grid class="overflow-x-hidden" :cols="9">
      <n-gi v-for="(item, index) in searchResultView" :key="itemKey(item)">
        <div
          class="flex hover:bg-[#eeeeee66] flex-col justify-around items-center w-90px h-90px cursor-pointer relative"
          :class="{ 'item-active': index === innerActiveIndex && activeIndex === sectionIndex }"
          @click="clickItem(item)"
          @contextmenu="contextmenu"
        >
          <n-image width="32" class="pt-4px" preview-disabled :src="item.icon" />

          <!-- dev 徽标 -->
          <span
            v-if="item.type === 'plugin' && item.dev"
            class="absolute right-10px top-4px bg-[#efefef] text-[#878787] rounded text-8px px-4px"
            >dev</span
          >
          <n-ellipsis
            class="pt-4px break-all text-12px line-height-1.4em text-center h-36px"
            style="max-width: 76px"
            :line-clamp="2"
            :tooltip="false"
          >
            <div v-html="renderSearchResult(itemName(item), item.from, item.to)"></div>
          </n-ellipsis>
        </div>
      </n-gi>
    </n-grid>
  </div>
</template>

<style scoped lang="scss"></style>
../utils
